#include "db_utils.h"

/*global*/
cmsDbContext_t dbCtx;
int dbModuleId = -1;
int resetFlag = 0;
int restoreDefaultFlag = 0;
extern pthread_mutex_t dbMtx;
//extern pthread_cond_t dbCond;
extern uint32_t saveCnt;


#ifdef DBUS_OBJECT_NOTIFY
extern cms_dbusNotify_t *g_dbusObj_list;
#endif

typedef void (*sighandler_t)(int);


int cmsDb_init(){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	int moduleId = -1;

	memset(&dbCtx, 0, sizeof(cmsDbContext_t));

	/*register cms_db to cmsCore*/
	moduleId = cms_registerModule(CMS_DB);
	if(moduleId < 0){
		CMS_LOG(LL_ERROR, "register module fail, get moduleId fail.\n");
		return -1;
	}else{
		dbCtx.moduleId = moduleId;
	}

	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}

int cmsDb_addObjByOID(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction, cmsBoolean taskNotifyFlag){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb= NULL;
	void *object = NULL;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "dbQ or msg action is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	CMS_LOG(LL_DEBUG, "before add object , oid %d, ia %"PRIx64"\n", pAction->object->objOffset.id, pAction->object->objOffset.IA);

	/*check object if has exist*/
	object = cmsXml_GetObjectByOID(xmlShmCb, pAction->object->objOffset.id, pAction->object->objOffset.IA, NULL_IF_NOT_EXISTED);
	if(object){
		CMS_LOG(LL_WARNING, "add object (%d %lx) has exist.", pAction->object->objOffset.id, pAction->object->objOffset.IA);
		dbQ->curObjIA = xmlShmCb->IA;
		dbQ->curObjId = xmlShmCb->OID;
		dbQ->curObjOffset = xmlShmCb->offset;
		return 0;
	}
	
	/*add object by OID*/
#ifdef GC_APPS_CTC
	if(dbQ->pMsg->header.srcModuleId ==cms_getModuleIdByName(CMS_DBUS))
		xmlShmCb->srcFromDbus = TRUE;
#endif
	object = cmsXmlAddObjByOID(xmlShmCb, pAction->object->objOffset.id, pAction->object->objOffset.IA, 0, NULL);
	if(object == NULL){
		CMS_LOG(LL_ERROR, "add object fail.\r\n");
		SET_NACK(pAction->action->type);
		return -1;
	}

	/*record new obj to list*/
	if(taskNotifyFlag == TRUE)
		cmsDb_recordObjChg(dbQ, xmlShmCb, object, CMS_DB_ADD_OBJECT);
	
	/*record current object info to dbQ*/
	dbQ->curObjIA = xmlShmCb->IA;
	dbQ->curObjId = xmlShmCb->OID;
	dbQ->curObjOffset = xmlShmCb->offset;

	CMS_LOG(LL_DEBUG, "********************** cur  , objID %d, objIA %"PRIx64", objOffset %d\n",
			dbQ->curObjId, dbQ->curObjIA, dbQ->curObjOffset);

	CMS_LOG(LL_DEBUG, "Exit.\n");
	
	return 0;
}

int cmsDb_addObjByPath(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction, cmsBoolean taskNotifyFlag){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb= NULL;
	void *object = NULL;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "dbQ or msg action is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	CMS_LOG(LL_DEBUG, "before add object , obj path name is %s\n", pAction->object->objName.objName);
	
	/*check object if has exist*/
	object = cmsXml_getObjectByPathName(xmlShmCb, pAction->object->objName.objName);
	if(object){
		CMS_LOG(LL_WARNING, "add object (%s) has exist.", pAction->object->objName.objName);
		dbQ->curObjIA = xmlShmCb->IA;
		dbQ->curObjId = xmlShmCb->OID;
		dbQ->curObjOffset = xmlShmCb->offset;
		return 0;
	}
	
	/*add object by OID*/
#ifdef GC_APPS_CTC
	if(dbQ->pMsg->header.srcModuleId ==cms_getModuleIdByName(CMS_DBUS))
		xmlShmCb->srcFromDbus = TRUE;
#endif
	object = cmsXmlAddObjByPathName(xmlShmCb, pAction->object->objName.objName, 0, NULL);
	if(object == NULL){
		CMS_LOG(LL_ERROR, "add object fail.\r\n");
		SET_NACK(pAction->action->type);
		return -1;
	}

	/*record new obj to list*/
	if(taskNotifyFlag == TRUE)
		cmsDb_recordObjChg(dbQ, xmlShmCb, object, CMS_DB_ADD_OBJECT);
	
	/*record current object info to dbQ*/
	dbQ->curObjIA = xmlShmCb->IA;
	dbQ->curObjId = xmlShmCb->OID;
	dbQ->curObjOffset = xmlShmCb->offset;

	CMS_LOG(LL_DEBUG, "****************cur obj offset is %d\n", dbQ->curObjOffset);

	CMS_LOG(LL_DEBUG, "Exit.\n");
	
	return 0;
}

int cmsDb_delObjByOID(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction, cmsBoolean taskNotifyFlag){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb= NULL;
	objectList_t *objChildList= NULL;
	void *object = NULL;
	void *childObject = NULL;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "dbQ or msg action is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	object = cmsXml_GetObjectByOID(xmlShmCb, pAction->object->objOffset.id, pAction->object->objOffset.IA, NULL_IF_NOT_EXISTED);
	if(object){
		CMS_LOG(LL_DEBUG, "before del object by oid , oid %d, ia %"PRIx64"\n", pAction->object->objOffset.id, pAction->object->objOffset.IA);
		if(taskNotifyFlag == TRUE)
		{
			/*del object by OID, and record*/
			object = cmsXml_GetObjectByOID(xmlShmCb, pAction->object->objOffset.id, pAction->object->objOffset.IA, NULL_IF_NOT_EXISTED);
			cmsDb_recordObjChg(dbQ, xmlShmCb, object, CMS_DB_DEL_OBJECT);
			
			/*recode the child object of this object*/
			objChildList = cmsXml_GetFullChildList(xmlShmCb, pAction->object->objOffset.id, pAction->object->objOffset.IA);
			while(objChildList){

				childObject = cmsXml_GetObjectByOID(xmlShmCb, objChildList->OID, objChildList->IA, NULL_IF_NOT_EXISTED);
				if(childObject)
					cmsDb_recordObjChg(dbQ, xmlShmCb, childObject, CMS_DB_DEL_OBJECT);
				
				objChildList = objChildList->next;
			}
			if(objChildList)
				cmsXml_FreeObjList(&objChildList);
		}
#ifdef GC_APPS_CTC
		if(dbQ->pMsg->header.srcModuleId ==cms_getModuleIdByName(CMS_DBUS))
			xmlShmCb->srcFromDbus = TRUE;
#endif
		cmsXmlDelObjByOID(xmlShmCb, pAction->object->objOffset.id, pAction->object->objOffset.IA);

		SET_ACK(pAction->action->type);
	
	}else{
		CMS_LOG(LL_ERROR, "object has been deleted.\n");
		
		SET_NACK(pAction->action->type);
		return -1;
	}

	CMS_LOG(LL_DEBUG, "****************cur obj offset is %d\n", dbQ->curObjOffset);

	CMS_LOG(LL_DEBUG, "Exit.\n");
	
	return 0;
}

int cmsDb_delObjByPath(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction, cmsBoolean taskNotifyFlag){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb= NULL;
	objectList_t *objChildList= NULL, *pCurObj = NULL;
	void *object = NULL;
	void *childObject = NULL;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "dbQ or msg action is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	object = cmsXml_GetObjectByName(xmlShmCb, pAction->object->objName.objName, NULL_IF_NOT_EXISTED);
	if(object){
		if(taskNotifyFlag == TRUE)
		{
			CMS_LOG(LL_DEBUG, "before del object by path , obj path name is %s\n", pAction->object->objName.objName);
			/*del object by name path*/
			object = cmsXml_GetObjectByName(xmlShmCb, pAction->object->objName.objName, NULL_IF_NOT_EXISTED);
			cmsDb_recordObjChg(dbQ, xmlShmCb, object, CMS_DB_DEL_OBJECT);

			pCurObj = cmsXml_GetObjListByName(xmlShmCb, pAction->object->objName.objName);
			if(pCurObj != NULL){
				/*recode the child object of this object*/
				objChildList = cmsXml_GetFullChildList(xmlShmCb, pCurObj->OID, pCurObj->IA);
				cmsXml_FreeObjList(&pCurObj);
				while(objChildList){

					childObject = cmsXml_GetObjectByOID(xmlShmCb, objChildList->OID, objChildList->IA, NULL_IF_NOT_EXISTED);
					if(childObject)
						cmsDb_recordObjChg(dbQ, xmlShmCb, childObject, CMS_DB_DEL_OBJECT);
					
					objChildList = objChildList->next;
				}
				if(objChildList)
					cmsXml_FreeObjList(&objChildList);
			}
		}
#ifdef GC_APPS_CTC
		if(dbQ->pMsg->header.srcModuleId ==cms_getModuleIdByName(CMS_DBUS))
			xmlShmCb->srcFromDbus = TRUE;
#endif		
		cmsXmlDelObjByPathName(xmlShmCb, pAction->object->objName.objName);

		SET_ACK(pAction->action->type);

	}else{
		CMS_LOG(LL_ERROR, "object has been deleted.\n");
		
		SET_NACK(pAction->action->type);
		return -1;
	}
	
	CMS_LOG(LL_DEBUG, "****************cur obj offset is %d\n", dbQ->curObjOffset);

	CMS_LOG(LL_DEBUG, "Exit.\n");
	
	return 0;
}

int cmsDb_getObj(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsMsgCb_t *objParaMsg = NULL;
	void **paraNameList = NULL;
	char *objPathName = NULL;
	
	parameterValue_t *parameterValue = NULL;
	uintptr_t *parameter;
	char **temp;
	uint32_t shmSize = 0;  /*the shmSize created to store parameter info*/
	int i = 0;

	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}

	objPathName = cmsXml_GetFullpathByOIDIA(pAction->object->objOffset.id, pAction->object->objOffset.IA);
	CMS_LOG(LL_DEBUG, "object pathName %s, id %d, IA %"PRIx64".\n", objPathName, pAction->object->objOffset.id, pAction->object->objOffset.IA);
	if(objPathName){
		paraNameList = cmsXml_GetParameterNameByObjectName(dbQ->xmlShmCb,objPathName);

		cmsXml_GetObjectByName(dbQ->xmlShmCb, objPathName, NULL_IF_NOT_EXISTED);
		cmsXml_freeFullPathBuffer((void *)&objPathName);
		/*compute total size of parameter info need*/
		shmSize = sizeof(cmsMsg_header_t) + sizeof(actionType_t) + dbQ->xmlShmCb->objectSize;

		/*create msg by shmSize*/
		objParaMsg = cms_createRequestMsg(shmSize);
		if(objParaMsg == NULL){
			CMS_LOG(LL_DEBUG, "create request msg fail.\n");
			cmsXml_freeParameterNameBuffer(paraNameList);
			safe_free(objPathName);
			return -1;
		}

		/*put para info to share memory*/
		for(i = 0; i < dbQ->xmlShmCb->meta_count; i++)
		{
			CMS_LOG(LL_DEBUG,"parameter num is %d, parameterName %s\n", dbQ->xmlShmCb->meta_count,(char *)*(paraNameList + i));
			parameter = malloc(sizeof(void *)*1);
			temp = (char **)parameter;
			*parameter = (uintptr_t)(*(paraNameList + i));
			parameterValue = (parameterValue_t *)cmsXmlGetParameter(dbQ->xmlShmCb, dbQ->xmlShmCb->offset, 1, temp);
			if((parameterValue->type_size & PARAMETER_TYPE_STRING) == PARAMETER_TYPE_STRING)
				CMS_LOG(LL_DEBUG,"parameter name %s, type 0x%x, value %s.\n", parameterValue->name, parameterValue->type_size, (char *)parameterValue->value);
			else 
				CMS_LOG(LL_DEBUG,"parameter name %s, type 0x%x, value %d.\n", parameterValue->name, parameterValue->type_size, *(uint8_t *)parameterValue->value);
			free(temp);
			
			cms_requestParaInfo(objParaMsg, parameterValue->name, parameterValue->type_size, parameterValue->value);
		}

		/*free*/
		cmsXml_freeParameterNameBuffer(paraNameList);

		/*send share memory to dst module*/
		CMS_LOG(LL_DEBUG,"dst module id %d=============\n",  dbQ->pMsg->header.srcModuleId);
		cms_objParaSent(objParaMsg, dbQ->pMsg->header.srcModuleId);

		cms_msgFree(objParaMsg);
	}

	safe_free(objPathName);
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}

int cmsDb_selObjByName(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb = NULL;
	void *obj = NULL;
	objectList_t *objList = NULL;
	cmsuint32 objIndex = 0;
	char objName[256] = {0};

	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}
	
	dbQ->curObjName = pAction->object->objName.objName;

	/*init shm & get obj by objName*/
	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	/*get object by objName*/
	obj = cmsXmlGetObjectByName(xmlShmCb, dbQ->curObjName);
	objIndex = xmlShmCb->objectIndex;
	if(obj != NULL){
		dbQ->curObjOffset = xmlShmCb->offset;
		SET_ACK(pAction->action->type);
		SET_ACK(dbQ->pMsg->header.flag);
	}else{
		dbQ->curObjOffset = 0;
		SET_NACK(pAction->action->type);
		SET_NACK(dbQ->pMsg->header.flag);
		objList = cmsXml_GetObjListByName(xmlShmCb,dbQ->curObjName);
		if(objList != NULL){
			dbQ->curObjId = objList->OID;
			dbQ->curObjIA = objList->IA;
			cmsXml_FreeObjList(&objList);
		}
		return -1;
	}

	if(objIndex != 0){
		strcpy(objName, pAction->object->objName.objName);
		sprintf(pAction->object->objName.objName, "%s.%u", objName, objIndex);
		xmlShmCb->objectIndex = 0;
	}

	dbQ->curObjOffset = xmlShmCb->offset;
	dbQ->curObjId = xmlShmCb->OID;
	dbQ->curObjIA = xmlShmCb->IA;
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}


int cmsDb_selObjById(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction)
{
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb = NULL;
	void *obj = NULL;

	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}
	
	dbQ->curObjId = pAction->object->objOffset.id;
	dbQ->curObjIA = pAction->object->objOffset.IA;

	/*init shm & get obj by oid*/
	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	/*get object by objID*/
	obj = cmsXmlGetObjectByOID(xmlShmCb, dbQ->curObjId, dbQ->curObjIA);
	if(obj != NULL){
		dbQ->curObjOffset = xmlShmCb->offset;
		SET_ACK(pAction->action->type);
	}else{
		dbQ->curObjOffset = 0;
		SET_NACK(pAction->action->type);
		return -1;
	}
	
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}

int cmsDb_selObjByOffset(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction)
{
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb = NULL;
	uint32_t objId;
	uint64_t objIA;
	void *obj = NULL;
	char *objFullPath = NULL;

	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "dbQ or msg Action  is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}
	
	/*get obj by offset*/
	obj = cmsXml_getObjectByID( xmlShmCb, pAction->object->objOffset.id);
	if(obj){

		/*get oid&IA by offset, and set to dbQ*/
		objId = cmsXml_GetOIDByOffset(xmlShmCb, pAction->object->objOffset.id);
		objIA = cmsXmlGetPreObjIA(xmlShmCb,pAction->object->objOffset.id);
		
		dbQ->curObjOffset = pAction->object->objOffset.id;
		dbQ->curObjId = objId;
		dbQ->curObjIA = objIA;
	}else{
		dbQ->curObjOffset = 0;
	}

	CMS_LOG(LL_DEBUG, "get object by offset id  %d, objId: %d, objIA: %"PRIx64"\n", dbQ->curObjOffset, dbQ->curObjId, dbQ->curObjIA);
	if(__CMS_LOG(LL_DEBUG)){
		objFullPath = cmsXml_getFullPathByID(xmlShmCb, dbQ->curObjOffset);
		CMS_LOG(LL_DEBUG, "get object: %s\n", objFullPath?objFullPath:"");
		cmsXml_freeFullPathBuffer((void **)&objFullPath);
	}
	
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}


int cmsDb_getParameter(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	uintptr_t *parameter;
	char **temp;
	parameterValue_t *pGet;
	cmsuint32 type = 0, type_size = 0;
	cmsoffset_t valueOffset;

	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}
	
	if(dbQ->curObjOffset == 0 || dbQ->xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "current object offset is 0.\n");
		SET_NACK(pAction->action->type);
		SET_NACK(dbQ->pMsg->header.flag);
		return -1;
	}

	parameter = malloc(sizeof(void*)*1);
	temp = (char **)parameter;
	*parameter = (uintptr_t)(&(pAction->parameter->parameterName));
	pGet = (parameterValue_t *)cmsXmlGetParameter(dbQ->xmlShmCb, dbQ->curObjOffset, 1, temp);
	free(temp);
	if(pGet == NULL){
		SET_NACK(pAction->action->type);
		SET_NACK(dbQ->pMsg->header.flag);
		pAction->paraValue->typeSizeOfValue = 0;
		return -1;
	}

	type = (pGet->type_size) & PARAMETER_TYPE_STRING;
	if(type == PARAMETER_TYPE_STRING){
		type_size = (strlen(pGet->value)+1)|PARAMETER_TYPE_STRING;
		valueOffset = cmsXmlGetPtrOffset(dbQ->xmlShmCb, pGet->value);
		SET_ACK(pAction->action->type);
		SET_ACK(dbQ->pMsg->header.flag);
		pAction->paraValue->typeSizeOfValue = type_size;
		memcpy(&(pAction->paraValue->value), &valueOffset, sizeof(cmsoffset_t));	
	}else{
		valueOffset = cmsXmlGetPtrOffset(dbQ->xmlShmCb, pGet->value);
		SET_ACK(pAction->action->type);
		SET_ACK(dbQ->pMsg->header.flag);
		pAction->paraValue->typeSizeOfValue = pGet->type_size;
		memcpy(&(pAction->paraValue->value), &valueOffset, sizeof(cmsoffset_t));	

	}

	CMS_LOG(LL_DEBUG, "****************parameter info , %s, 0x%x, %s\n", pAction->parameter->parameterName, 
		pAction->paraValue->typeSizeOfValue,  (char *)pGet->value);

	cmsXml_freeParameterBuffer(pGet, 1);
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}

int cmsDb_setParameter(
	cms_dbQueue_t *dbQ, 
	cmsMsg_action_t *pAction, 
	cmsBoolean taskNotifyFlag,
	cmsBoolean cwmpNotifyFlag)
{
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb= NULL;
	uint32_t attrFlag = 0;
	char *objectName = NULL;
	setParaValue_t param;
	parameterValue_t *oldParameterValue = NULL;
	uint8_t *oldObject = NULL;
	void *object = NULL;
	char *objFullPath = NULL;
	uint32_t type;
	int ret = -1;

	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}
	
	if(dbQ->curObjOffset == 0){
		CMS_LOG(LL_ERROR, "current obj offset is 0.\n");
		return -1;
	}

	if(pAction->paraValue->typeSizeOfValue == PARAMETER_TYPE_STRING)
		CMS_LOG(LL_DEBUG, "****************parameter info , %s, 0x%x, %s, id %d, Ia %"PRIx64", offset %d\n", pAction->parameter->parameterName, 
			pAction->paraValue->typeSizeOfValue, pAction->paraValue->value, 
			dbQ->curObjId, dbQ->curObjIA, dbQ->curObjOffset);
	else
		CMS_LOG(LL_DEBUG, "****************parameter info , %s, 0x%x, %d, id %d, Ia %"PRIx64", offset %d\n", pAction->parameter->parameterName, 
			pAction->paraValue->typeSizeOfValue, (*((uint8_t *)pAction->paraValue->value)), 
			dbQ->curObjId, dbQ->curObjIA, dbQ->curObjOffset);
	if(__CMS_LOG(LL_DEBUG)){
		objFullPath = cmsXml_getFullPathByID(dbQ->xmlShmCb, dbQ->curObjOffset);
		CMS_LOG(LL_DEBUG, "****************parameter info , obj: %s\n", objFullPath?objFullPath:"");
		cmsXml_freeFullPathBuffer((void **)&objFullPath);
	}
	
	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}
	cmsXml_GetObjectByOID(xmlShmCb,dbQ->curObjId,dbQ->curObjIA, NULL_IF_NOT_EXISTED);
	if(xmlShmCb->objectNode == NULL){
		CMS_LOG(LL_ERROR, "object(OID %d, OIA 0x%lx) has been del before set parameter.\n", dbQ->curObjId,dbQ->curObjIA);
		return -1;
	}
		
	/*get old object*/
	if(dbQ->recordObjFlag == 0){
		oldObject = malloc(xmlShmCb->objectNode->object_size & GET_OBJECT_SIZE_MASK);
		object = cmsXmlGetObjRealAddr(xmlShmCb, dbQ->curObjOffset);
		memcpy(oldObject, object, xmlShmCb->objectNode->object_size & GET_OBJECT_SIZE_MASK);
	}

	/*get old value of parameter*/
	memset(&param,0,sizeof(param));
	param.parameter=pAction->parameter->parameterName;
	oldParameterValue = cmsXmlGetParameter(xmlShmCb, dbQ->curObjOffset, 1, (char **)&param);
	if(oldParameterValue == NULL){
		char *fullObjPath = (char *)cmsXml_GetFullpathByOIDIA(cmsXml_GetOIDByOffset(xmlShmCb, dbQ->curObjOffset),dbQ->curObjIA);
		CMS_LOG(LL_ERROR, "can't found param %s(OID %d, OIA %lx, object name %s).\n", 
			pAction->parameter->parameterName, cmsXml_GetOIDByOffset(xmlShmCb, dbQ->curObjOffset),dbQ->curObjIA,
			(fullObjPath == NULL ? "" : fullObjPath));
		safe_free(fullObjPath);
		safe_free(oldObject);
		return -1;
	}
	//CMS_LOG(LL_DEBUG, "parameter(%s), old value is %s\n", pAction->parameter->parameterName, (char *)(oldParameterValue->value));
	
	
	/*set parameter new value*/
	/*put new info to structure*/
	type = pAction->paraValue->typeSizeOfValue;
	memset(&param,0,sizeof(param));
	param.parameter=pAction->parameter->parameterName;
	param.type=&type;
	param.value=pAction->paraValue->value;

	/*set value*/
	ret=cmsXmlSetParameter(xmlShmCb, dbQ->curObjOffset, 1, (char **)&param);
	CMS_LOG(LL_INFO, "set parameter %s ret %d\n",pAction->parameter->parameterName, ret);
	if(ret == CMS_NOK){
		CMS_LOG(LL_ERROR, "set parameter(%s) fail, please recovery the parameter value.\r\n", pAction->parameter->parameterName);

		/*set*/
		type = oldParameterValue->type_size;
		memset(&param,0,sizeof(param));
		param.parameter=oldParameterValue->name;
		param.type=&type;
		param.value=oldParameterValue->value;
		cmsXmlSetParameter(xmlShmCb, dbQ->curObjOffset, 1, (char **)&param);

		cmsXml_freeParameterBuffer(oldParameterValue, 1);
		safe_free(oldObject);
		return -1;
	}

	/*set new vaule success*/
	if(ret == CMS_NOCHANGE){
		goto exit;
	}
	
	if(ret != CMS_OUTOFRANGE){/*record changed object before notify tr069*/
#ifdef DBUS_OBJECT_NOTIFY
		cms_dbusNotify_t *curDbusObj = NULL, *tmpDbusObj = NULL;
		if(g_dbusObj_list == NULL){
			g_dbusObj_list = (cms_dbusNotify_t *)calloc(1, sizeof(cms_dbusNotify_t));
			g_dbusObj_list->objOff = dbQ->curObjOffset;
			strcpy(g_dbusObj_list->paramName, pAction->parameter->parameterName); 
		}else{
			curDbusObj = (cms_dbusNotify_t *)calloc(1, sizeof(cms_dbusNotify_t));
			curDbusObj->objOff = dbQ->curObjOffset;
			strcpy(curDbusObj->paramName, pAction->parameter->parameterName); 

			tmpDbusObj = g_dbusObj_list;
			while(tmpDbusObj->next){
				tmpDbusObj = tmpDbusObj->next;
			}
			tmpDbusObj->next = curDbusObj;
			curDbusObj->prev = tmpDbusObj;
			//INSERT_NODE(g_dbusObj_list, curDbusObj);
		}	
#endif
		if(taskNotifyFlag == TRUE)
			cmsDb_recordObjChg(dbQ, xmlShmCb, oldObject, CMS_DB_SET_OBJECT);
		
		/*tr069 feature, notify tr069 paramter changed which it's interested.*/
		attrFlag = cmsXml_getParameterAttr(xmlShmCb, dbQ->curObjOffset, pAction->parameter->parameterName);
		CMS_LOG(LL_INFO, "set parameter %s, it's attr %d, cwmpNotifyFlag %d",  pAction->parameter->parameterName, attrFlag, cwmpNotifyFlag);
		if((attrFlag & PARAMETER_ATTR_ACTIVENOTIFY) ||(attrFlag & PARAMETER_ATTR_PASSIVENOTIFY)){
			if((attrFlag & PARAMETER_ATTR_ACTIVENOTIFY) && (cwmpNotifyFlag == FALSE))//only send passive param to cwmp when set by cwmp
				goto exit;
			
			char *objFullPath = cmsXml_getFullPathByID(xmlShmCb, dbQ->curObjOffset);

			objectName = (char *)calloc(1, strlen(objFullPath) + strlen(pAction->parameter->parameterName)+strlen((char *)pAction->paraValue->value)+16);
			if(objectName == NULL){
				CMS_LOG(LL_ERROR, "calloc paramter info memory for cwmp fail.\n");
				cmsXml_freeFullPathBuffer((void *)&objFullPath);
				goto exit;
			}
			if(cwmpNotifyFlag == TRUE){//other app setting(not cwmp)
                uint8_t *pAp = pAction->paraValue->value;
				/*change the separation character into &,because the previous / may be included in some parameters,such as http://test */
				if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_STRING){
					if(strlen((char *)pAp) == 0){
						sprintf(objectName, "%s.%s&%d&%s", objFullPath, pAction->parameter->parameterName,CWMP_DATA_TYPE_STRING, "NULL");
					}else{
						sprintf(objectName, "%s.%s&%d&%s", objFullPath, pAction->parameter->parameterName,CWMP_DATA_TYPE_STRING, pAp);
					}
				}
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_UINT8)
					sprintf(objectName, "%s.%s&%d&%u", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_UNSIGNED_INT, *(uint8_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_UINT16)
					sprintf(objectName, "%s.%s&%d&%u", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_UNSIGNED_INT, *(uint16_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_UINT32)
					sprintf(objectName, "%s.%s&%d&%u", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_UNSIGNED_INT, *(uint32_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_UINT64)
					sprintf(objectName, "%s.%s&%d&%"PRIu64"", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_UNSIGNED_INT, *(uint64_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_SINT7)
					sprintf(objectName, "%s.%s&%d&%d", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_INT, *(int8_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_SINT15)
					sprintf(objectName, "%s.%s&%d&%d", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_INT, *(int16_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_SINT31)
					sprintf(objectName, "%s.%s&%d&%d", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_INT, *(int32_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_SINT63)
					sprintf(objectName, "%s.%s&%d&%"PRId64"", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_INT, *(int64_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_DATETIME)
					sprintf(objectName, "%s.%s&%d&%s", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_DATETIME, pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_BOOLEAN)
					sprintf(objectName, "%s.%s&%d&%d", objFullPath, pAction->parameter->parameterName, CWMP_DATA_TYPE_BOOLEAN, *(uint8_t *)pAp);
				else if(pAction->paraValue->typeSizeOfValue  == PARAMETER_TYPE_MAC){
					unsigned char mac[6] = {0};
					memcpy(mac,  pAp, 6);
					sprintf(objectName, "%s.%s&%d&%02x:%02x:%02x:%02x:%02x:%02x", 
						objFullPath, pAction->parameter->parameterName, 
						CWMP_DATA_TYPE_STRING,
						mac[0],
						mac[1],
						mac[2],
						mac[3],
						mac[4],
						mac[5]);
				}
				else
					sprintf(objectName, "%s.%s&%d&%s", objFullPath, pAction->parameter->parameterName,CWMP_DATA_TYPE_STRING, pAp);

				if(attrFlag & PARAMETER_ATTR_ACTIVENOTIFY){
					cms_eventNotify(CMS_EVENT_NOTIFY_ACTIVE, PARAMETER_TYPE_STRING, objectName);
				}else if(attrFlag & PARAMETER_ATTR_PASSIVENOTIFY){
					cms_eventNotify(CMS_EVENT_NOTIFY_PASSIVE, PARAMETER_TYPE_STRING, objectName);
				}
			}else{//cwmp set paramter
				sprintf(objectName, "%s.%s", objFullPath, pAction->parameter->parameterName);
				cms_eventNotify(CMS_EVENT_NOTIFY_CWMP_SETTING, PARAMETER_TYPE_STRING, objectName);
			}

			CMS_LOG(LL_INFO, "set parameter %s, it's value %s\n",  pAction->parameter->parameterName, objectName);
			
			free(objectName);
			cmsXml_freeFullPathBuffer((void *)&objFullPath);
		}
		//else
		#if 0
			{
			if(!strcmp(pAction->parameter->parameterName, "URL")){
				char *objFullPath = cmsXml_getFullPathByID(xmlShmCb, dbQ->curObjOffset);
				if(!strcmp(objFullPath, "InternetGatewayDevice.ManagementServer")){
					objectName = (char *)calloc(1, strlen(objFullPath) + strlen(pAction->parameter->parameterName)+strlen((char *)pAction->paraValue->value)+16);
					if(objectName == NULL){
						CMS_LOG(LL_ERROR, "calloc paramter info memory for cwmp fail.\n");
						cmsXml_freeFullPathBuffer((void *)&objFullPath);
						goto exit;
					}

					sprintf(objectName, "%s.%s&%d&%s", objFullPath, pAction->parameter->parameterName,CWMP_DATA_TYPE_STRING, pAction->paraValue->value);
					cms_eventNotify(CMS_EVENT_NOTIFY_CWMP_INFORM, PARAMETER_TYPE_STRING, objectName);

					free(objectName);
				}
				cmsXml_freeFullPathBuffer((void *)&objFullPath);
			}
			else if(!strcmp(pAction->parameter->parameterName, "Password")){
				char *objFullPath = cmsXml_getFullPathByID(xmlShmCb, dbQ->curObjOffset);
				if(!strcmp(objFullPath, "InternetGatewayDevice.X_CT-COM_UserInfo")){
					objectName = (char *)calloc(1, strlen(objFullPath) + strlen(pAction->parameter->parameterName)+strlen((char *)pAction->paraValue->value)+16);
					if(objectName == NULL){
						CMS_LOG(LL_ERROR, "calloc paramter info memory for cwmp fail.\n");
						cmsXml_freeFullPathBuffer((void *)&objFullPath);
						goto exit;
					}

					sprintf(objectName, "%s.%s&%d&%s", objFullPath, pAction->parameter->parameterName,CWMP_DATA_TYPE_STRING, pAction->paraValue->value);
					cms_eventNotify(CMS_EVENT_NOTIFY_CWMP_INFORM, PARAMETER_TYPE_STRING, objectName);

					free(objectName);
				}
				cmsXml_freeFullPathBuffer((void *)&objFullPath);
			}

		}
	#endif
		
	}else{
		CMS_LOG(LL_WARNING, "set parameter same value.\r\n");

		cmsXml_freeParameterBuffer(oldParameterValue, 1);
		safe_free(oldObject);
		return -1;
	}

exit:
	cmsXml_freeParameterBuffer(oldParameterValue, 1);
	safe_free(oldObject);
	CMS_LOG(LL_DEBUG, "Exit.\n");

	if(ret == CMS_NOCHANGE){
		/*set new vaule no change, should be treated as success*/
		ret = CMS_OK;
	}
	return ret;
}


int cmsDb_getParaAttr(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb = NULL;
	char *parameter = NULL;
	uint32_t attr = 0;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	parameter = (char *)(&(pAction->paraAttr->parameter.parameterName));

	/*get attr*/
	attr = cmsXmlGetParameterAttr(xmlShmCb,dbQ->curObjOffset,parameter);
	pAction->paraAttr->attr = attr;

	CMS_LOG(LL_DEBUG, "get attr is %s, attr is %d\n", parameter, attr);
		
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}

int cmsDb_setParaAttr(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	cmsXmlCb_t *xmlShmCb = NULL;
	char *parameter = NULL;
	uint32_t attr;
	uint32_t active;
	int ret = -1;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return -1;
	}

	/*get parameter & attr for action*/
	parameter = (char *)(&(pAction->paraAttr->parameter.parameterName));
	attr = pAction->paraAttr->attr;
	active = pAction->paraAttr->active;
	CMS_LOG(LL_DEBUG,"set attr, paraName: %s, attr is %d, active is %d.\n", parameter, attr, active);
	/*set attr*/
	ret = cmsXmlSetParameterAttr(xmlShmCb,dbQ->curObjOffset,parameter,attr,active);
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return ret;
}

int cmsDb_save(cms_dbQueue_t *dbQ){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	int ret = -1;

	if(resetFlag == 1){
		CMS_LOG(LL_ERROR, "cms reset or upload xml has happen, please wait reboot.\n");
		return ret;
	}

	pthread_mutex_lock(&dbMtx);
	saveCnt++;
	ret = 0;
	pthread_mutex_unlock(&dbMtx);
	
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return ret;
}

int cmsDb_handleApply(cms_dbQueue_t *dbQ, cmsMsg_header_t *msgHeader){
	cmsMsgCb_t *objDataMsg = NULL;
	cms_objChgList_t *curObjChg = NULL, *tmpObjChg = NULL;
	uint32_t notifyFlag = 0;
	uint32_t objChgNum = 0;
	uint32_t shmSize = 0;
	uint32_t objDataSize = 0;


	if(dbQ == NULL){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}

	/*check if need valid, "delete/add" no need to valid, "set" need to valid*/
	curObjChg = dbQ->objChgList;
	while(curObjChg){
		notifyFlag = 0;

		if(curObjChg->flag == CMS_DB_DEL_OBJECT){
			notifyFlag = CMS_DB_OBJECT_CHG_NOTIFY;
			curObjChg->flag |= CMS_DB_OBJECT_CHG_NOTIFY;
		}else {

			/*valid the object with id & ia*/
			//XXXXXXXXXXXXXXXXXXXXXX

			/*valid ok, set the follow flag*/
			notifyFlag = CMS_DB_OBJECT_CHG_NOTIFY;
			curObjChg->flag |= CMS_DB_OBJECT_CHG_NOTIFY;
		}

		/*statistics the num of chaged object*/
		if(notifyFlag == CMS_DB_OBJECT_CHG_NOTIFY){
			if((curObjChg->flag & CMS_DB_SET_OBJECT) == CMS_DB_SET_OBJECT)/*set para need store old data & need data*/
				objDataSize += (curObjChg->objSize)*2;
			else
				objDataSize += (curObjChg->objSize)*1;
			
			objChgNum++;
		}
		
		curObjChg = curObjChg->next;
	}

	CMS_LOG(LL_DEBUG, "before send object changed to task, objNum is %d==================\n",objChgNum);
	/*check object changed num, if > 0, send to task module*/
	if(objChgNum > 0){
		/*calc total size of objchg which will send by msg*/
		shmSize = sizeof(cmsMsg_header_t) + sizeof(actionType_t) + sizeof(objectChgData_t)*objChgNum + objDataSize*2;
		
		/*create msg by shmSize*/
		objDataMsg = cms_createRequestMsg(shmSize);
		if(objDataMsg == NULL){
			CMS_LOG(LL_DEBUG, "create request msg fail.\n");
			return -1;
		}

		objDataMsg->header.isMutliObj = msgHeader->isMutliObj;
		
		cms_requestSetModuleId(objDataMsg, msgHeader->srcModuleId);
		
		/*add obj to request*/
		curObjChg = dbQ->objChgList;
		while(curObjChg){
			if((curObjChg->flag & CMS_DB_OBJECT_CHG_NOTIFY) == CMS_DB_OBJECT_CHG_NOTIFY){
				curObjChg->flag &= ~ CMS_DB_OBJECT_CHG_NOTIFY;

				CMS_LOG(LL_DEBUG, "cur  object  size is %d, flag 0x%x,  objId %d, objIA %"PRIx64"\n",curObjChg->objSize, curObjChg->flag,curObjChg->objId, curObjChg->objIA);
				cms_requestObjChange(objDataMsg,\
					0, \
					curObjChg->objId,\
					curObjChg->objIA,\
					curObjChg->flag,\
					curObjChg->objSize,\
					curObjChg->oldObject,\
					curObjChg->newObject);
			}

			/*remove objchg*/
			tmpObjChg = curObjChg;
			curObjChg = curObjChg->next;
			safe_free(tmpObjChg->oldObject);
			safe_free(tmpObjChg->newObject);
			DELETE_NODE(dbQ->objChgList, tmpObjChg);
		}

		/*send*/
		if(cms_objChgNotify(objDataMsg) == CMS_NOK){
			cms_msgAndShmFree(objDataMsg);
			return CMS_NOK;
		}
		
		cms_msgFree(objDataMsg);
		
	}

	return 0;
}

static int cmsDb_exampleRestoreDefaule(cmsXmlCb_t *xmlShmCb, cmsXmlCb_t *defXmlShmCb, uint32_t restoreType, uint32_t restoreSource)
{
    /***********************
     * example code
     * ...
     **********************/

    return CMS_OK;
}

int cmsDb_restoreDefault(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");

	cmsXmlCb_t *xmlShmCb= NULL;
	cmsXmlCb_t *defXmlShmCb= NULL;
	char cmdline[148]={0};
	char tmpCmsFileName[128]={0};
	uint32_t restoreTypeValue = RESTORE_TYPE_SHORT;
	uint32_t restoreType = RESTORE_TYPE_SHORT;
	uint32_t restoreSource = RESTORE_SOURE_NONE;
	int rebootReason = REBOOT_NONE_RESTORE;
	int ret = -1;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}

	resetFlag = 0;
	restoreDefaultFlag = 0;
	restoreTypeValue = pAction->eventContent->typeSizeOfValue;
	restoreType = cmsRestoreType(restoreTypeValue);
	restoreSource = cmsRestoreSource(restoreTypeValue);
	
	CMS_LOG(LL_INFO, "restore default, restoreType=%d source=%d.\n",restoreType, restoreSource);

	xmlShmCb = dbQ->xmlShmCb;
	if(xmlShmCb==NULL){
		CMS_LOG(LL_ERROR, "db xmlshmcb is NULL.\n");
		return CMS_NOK;
	}
	
	defXmlShmCb = XMLSHM_DEFAULT_INIT();
	if(defXmlShmCb==NULL){
		CMS_LOG(LL_ERROR, "db defxmlshmcb init fail.\n");
		return CMS_NOK;
	}

	/*remove syslog file while reset*/
	if(restoreType == RESTORE_TYPE_SHORT || restoreType == RESTORE_TYPE_LONG){
#ifdef CMS_SUPPORT_YL
		libgc_sys_eraseBackupConfig();
#endif
		cms_do_cmd("echo 1 > /tmp/clearsyslog");	
		cms_do_cmd("rm -rf /userconfig/config/messages*");
		cms_do_cmd("rm -rf /userconfig/config/syslog*");
	}

    /***********************************************
     * customized default operation start
     * ********************************************/
    if(cmsDb_exampleRestoreDefaule(xmlShmCb, defXmlShmCb, restoreType, restoreSource) == CMS_NOK){
        CMS_LOG(LL_ERROR, "example restore default fail!");
        goto _Fail;
    }
    /***********************************************
     * customized default operation end
     * ********************************************/

	if(defXmlShmCb && defXmlShmCb->xmlFileName && xmlShmCb && xmlShmCb->xmlFileName){
		strcpy(defXmlShmCb->xmlFileName,xmlShmCb->xmlFileName);
	}
	if(defXmlShmCb && defXmlShmCb->cmsFileName && xmlShmCb && xmlShmCb->cmsFileName){
		strcpy(tmpCmsFileName,defXmlShmCb->cmsFileName);
		strcpy(defXmlShmCb->cmsFileName,xmlShmCb->cmsFileName);
	}

	if(restoreDefaultFlag != 1)/*reset action no need save current*/
	{
		ret = cmsXmlSave(defXmlShmCb); //save all xml for vlan id and relate information
		if(ret != 0){
			CMS_LOG(LL_ERROR, "cms xml save failed.\n");
		}
	}

	if(strlen(tmpCmsFileName)>0){
		sprintf(cmdline,"rm -rf %s",tmpCmsFileName);
		cms_do_cmd(cmdline);
	}
	XMLSHM_DEFAULT_DEINIT(defXmlShmCb);
	
	/*event notify to reboot*/
	if(restoreSource == RESTORE_SOURE_NONE)
		rebootReason = REBOOT_NONE_RESTORE;
	else if(restoreSource == RESTORE_SOURE_CLI)
		rebootReason = REBOOT_CLI_RESTORE;
	else if(restoreSource == RESTORE_SOURE_BUTTON)
		rebootReason = REBOOT_BUTTON_RESTORE;
	else if(restoreSource == RESTORE_SOURE_WEB)
		rebootReason = REBOOT_WEB_RESTORE;
	else if(restoreSource == RESTORE_SOURE_TR069)
		rebootReason = REBOOT_TR069_RESTORE;
	else if(restoreSource == RESTORE_SOURE_DBUS)
		rebootReason = REBOOT_DBUS_RESTORE;
	else if(restoreSource == RESTORE_SOURE_OSGI)
		rebootReason = REBOOT_OSGI_RESTORE;
	else if(restoreSource == RESTORE_SOURE_UBUS)
		rebootReason = REBOOT_UBUS_RESTORE;	
	
	rebootReason = rebootReason | (restoreType << 8);
	ret = cms_eventNotify(CMS_EVENT_REBOOT, sizeof(rebootReason), &rebootReason);
	/*event notify to reboot --end*/
	if(ret == CMS_OK){
		resetFlag = 1;
	}else{
		CMS_LOG(LL_ERROR, "reboot event notify send fail!!!\n");
		resetFlag = 0;
		return CMS_NOK;
	}
	
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return CMS_OK;

_Fail:
	if(strlen(tmpCmsFileName)>0){
		sprintf(cmdline,"rm -rf %s",tmpCmsFileName);
		cms_do_cmd(cmdline);
	}
	XMLSHM_DEFAULT_DEINIT(defXmlShmCb);
	return CMS_NOK;
}

#if 1
int cmsDb_restoreConf(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	char *fileName = NULL;
	char cmd[128] = {0};
	int ret = -1;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.");
		return -1;
	}

	resetFlag = 0;
	fileName = pAction->file->fileName;

	CMS_LOG(LL_NOTICE, "restore conf file %s.",fileName);

	if(fileName == NULL){
		CMS_LOG(LL_ERROR, "file name is NULL.");
		return -1;
	}else{
		if(access(fileName, F_OK) != 0){
			CMS_LOG(LL_ERROR, "file is miss.");
			return -1;
		}

		if(pAction->action->type == CMS_MSG_ACT_PRE_DEFAULT){
#ifdef CMS_SUPPORT_YL
			if( lib_sys_savePreConfig(fileName) == 1){
				CMS_LOG(LL_ERROR, "save pre xml(%s) download to pre partition fail!!!",fileName);
				return CMS_NOK;
			}else{
				if(libgc_sys_eraseBackupConfig() == 1){
					CMS_LOG(LL_ERROR, "erase backup partition fail");
					return CMS_NOK;
				}
			    snprintf(cmd, sizeof(cmd) - 1, "rm -rf %s/config.current.*", CUR_XML_PATH);
			    cms_do_cmd(cmd);
			}	
#endif
		}else if(pAction->action->type == CMS_MSG_ACT_RESTORECONF){
			snprintf(cmd, sizeof(cmd) - 1, "rm -rf %s/config.current.*", CUR_XML_PATH);
			cms_do_cmd(cmd);
			snprintf(cmd, sizeof(cmd) - 1, "mv %s %s", fileName, CMS_CUR_FILE_ENC);
			cms_do_cmd(cmd);
			snprintf(cmd, sizeof(cmd) - 1, "md5sum %s > %s", CMS_CUR_FILE_ENC, CMS_CUR_ENC_CRC);
			cms_do_cmd(cmd);
		}
	}

	/*event notify to reboot*/
	ret = cms_eventNotify(CMS_EVENT_REBOOT, 0, NULL);
	if(ret == CMS_OK){
		resetFlag = 1;
	}else{
		CMS_LOG(LL_ERROR, "reboot event notify send fail!!!\n");
		resetFlag = 0;
		return CMS_NOK;
	}
	
	return 0;
}


#else
int cmsDb_restoreConf(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");
	char *fileName = NULL;
	char resotreConf[128] = {0};
	int index=0,ret=-1;
	cmsXmlCb_t *xmlShmCb= NULL;
	cmsXmlCb_t *defXmlShmCb= NULL;
	void *object = NULL;
	void *curObject = NULL;

	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return -1;
	}

	fileName = pAction->file->fileName;

	CMS_LOG(LL_DEBUG, "restore conf file %s.\n",fileName);

	if(fileName == NULL){
		CMS_LOG(LL_ERROR, "file name is NULL.\n");
		return -1;
	}else{
		if(access(fileName, F_OK) != 0){
			CMS_LOG(LL_ERROR, "file is miss.\n");
			return -1;
		}
#if 0
		char file[128]={0};
		sprintf(file, "cp -rf %s /tmp/config.current111.xml", fileName);
		cms_do_cmd(file);
		
		cms_do_cmd("rm -rf /userconfig/config/config.current.*");
		
		sprintf(resotreConf, "mv %s %s", fileName, CMS_CUR_FILE_XML);
		cms_do_cmd(resotreConf);

#endif 
	
		// TODO: Add CWMP eventcode  into xml

		xmlShmCb = dbQ->xmlShmCb;
		if(xmlShmCb==NULL)
			return -1;
		
		defXmlShmCb = XMLSHMALLOC();
		if(defXmlShmCb==NULL){
			XMLSHMDEINIT(xmlShmCb);
			return -1;
		}
		
		objectNode_t *curEventObjNode,*defEventObjNode;
		for(index=0;index<InternetGatewayDevice_EventStruct_i_Max;index++){
			object= cmsXml_GetObjectByOID(xmlShmCb, OID_InternetGatewayDevice_EventStruct_i,cmsXmlConstructIAValue(1, "%d", index+1),NULL_IF_NOT_EXISTED);
			if(object==NULL){
				continue;
			}
			curEventObjNode = xmlShmCb->objectNode;

			curObject= cmsXml_GetObjectByOID(defXmlShmCb, OID_InternetGatewayDevice_EventStruct_i,cmsXmlConstructIAValue(1, "%d", index+1),NULL_IF_NOT_EXISTED);
			if(curObject==NULL){
				continue;
			}
			defEventObjNode = defXmlShmCb->objectNode;
			cmsXml_CopyRdmObjectNodeToDstRdmNode(xmlShmCb,defXmlShmCb,curEventObjNode,defEventObjNode,COPY_OBJECT_VALUE);
		}
		if(defXmlShmCb && defXmlShmCb->xmlFileName && xmlShmCb && xmlShmCb->xmlFileName){
			strcpy(defXmlShmCb->xmlFileName,xmlShmCb->xmlFileName);
		}
		/*if(defXmlShmCb && defXmlShmCb->cmsFileName && xmlShmCb && xmlShmCb->cmsFileName){
			strcpy(tmpCmsFileName,defXmlShmCb->cmsFileName);
			strcpy(defXmlShmCb->cmsFileName,xmlShmCb->cmsFileName);
		}*/
		
		ret = cmsXmlSave(defXmlShmCb); //save all xml for vlan id and relate information
		if(ret != 0){
			CMS_LOG(LL_ERROR, "cms xml save failed.\n");
		}

	}

	/*event notify to reboot*/
	cms_eventNotify(CMS_EVENT_REBOOT, 0, NULL);
	
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return 0;
}

#endif

int cmsDb_objValueRestore(cms_dbQueue_t *dbQ, cmsMsg_action_t *pAction){
	CMS_LOG(LL_DEBUG, "Entrance.\n");

	cmsXmlCb_t	*xmlShmCb= NULL;
	cmsXmlCb_t	*defXmlShmCb= NULL;
	void		*object = NULL;
	uint32_t	objId = 0;
	uint64_t	objIA = 0;
	uint32_t 	restoreType = 0;
	int 		ret = -1;
	
	if((dbQ == NULL) || (pAction == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.\n");
		return CMS_NOK;
	}

	xmlShmCb = dbQ->xmlShmCb;
	if (xmlShmCb == NULL){
		CMS_LOG(LL_ERROR, "xmlShm init error.\r\n");
		return CMS_NOK;
	}

	XML_LOCK(&xmlShmCb->cmsMutex->lock);
	/*get obj by offset*/
	object = cmsXml_getObjectByID( xmlShmCb, pAction->object->objOffset.id);
	if(object){
		/*get oid&IA by offset, and set to dbQ*/
		objId = cmsXml_GetOIDByOffset(xmlShmCb, pAction->object->objOffset.id);
		objIA = cmsXmlGetPreObjIA(xmlShmCb,pAction->object->objOffset.id);
		
		dbQ->curObjOffset = pAction->object->objOffset.id;
		dbQ->curObjId = objId;
		dbQ->curObjIA = objIA;
	}else{
		CMS_LOG(LL_ERROR, "object is not exist, objoffset is %u", pAction->object->objOffset.id);
		XML_UNLOCK(&xmlShmCb->cmsMutex->lock);
		return CMS_NOK;
	}

	restoreType = pAction->object->objOffset.shmId;

	CMS_LOG(LL_INFO, "get object by offset id: %d, objId: %d, objIA: 0x%lx, restoreType: %u\n", 
		dbQ->curObjOffset, dbQ->curObjId, dbQ->curObjIA, restoreType);

	switch(restoreType){
		case 1:
			defXmlShmCb = XMLSHM_DEFAULT_INIT();
			if(defXmlShmCb != NULL){
				void *object = cmsXmlGetObjectByOID(defXmlShmCb, dbQ->curObjId, dbQ->curObjIA);
				if(object != NULL){
					ret = cmsXml_CopyRdmObjectNodeToDstRdmNode(defXmlShmCb,xmlShmCb,defXmlShmCb->objectNode,xmlShmCb->objectNode,COPY_OBJECT_VALUE);		
				}else{
					ret = cmsXml_objectRestore(xmlShmCb, dbQ->curObjOffset);
				}
				XMLSHM_DEFAULT_DEINIT(defXmlShmCb);
			}else{
				ret = cmsXml_objectRestore(xmlShmCb, dbQ->curObjOffset);
			}
			break;
		case 2:
			ret = cmsXml_objectRestore(xmlShmCb, dbQ->curObjOffset);
			break;
		default:
			CMS_LOG(LL_ERROR, "not support restoreType %u", restoreType);
			break;
	}

	XML_UNLOCK(&xmlShmCb->cmsMutex->lock);
	CMS_LOG(LL_DEBUG, "Exit.\n");
	return ret;
}


int cmsDb_recordObjChg(cms_dbQueue_t *dbQ,  cmsXmlCb_t *xmlShmCb, void *object, uint32_t flag){
	cms_objChgList_t *curObjChg = NULL;
	void *newObjPtr = NULL;
	uint32_t conflictFlag = 0;
	static uint32_t flagRecord = 0;

	
	if((dbQ == NULL) || (xmlShmCb == NULL)){
		CMS_LOG(LL_ERROR, "parameter is NULL.");
		return -1;
	}


	CMS_LOG(LL_INFO,"shm id %d, ia %"PRIx64", flag: 0x%x\n", xmlShmCb->OID, xmlShmCb->IA, flag);

	/*check if has exist in list*/
	curObjChg = dbQ->objChgList;
	while(curObjChg){
		CMS_LOG(LL_DEBUG, "in record chg , oid %d,  ia %"PRIx64", flag: 0x%x\n", curObjChg->objId,curObjChg->objIA, curObjChg->flag);
		if((curObjChg->objId == xmlShmCb->OID) && (curObjChg->objIA == xmlShmCb->IA) && (flagRecord == flag)){
			conflictFlag = 2;
			break;
		}else if((curObjChg->objId == xmlShmCb->OID) && (curObjChg->objIA == xmlShmCb->IA) && 
			(flagRecord == CMS_DB_ADD_OBJECT) && (flag == CMS_DB_SET_OBJECT)){
			conflictFlag = 1;
			break;
		}
		curObjChg = curObjChg->next;
	}

	/*record obj*/
	if(conflictFlag == 1){/*action as, add first, then set parameter*/
		if(dbQ->recordObjFlag != 1){
			if(object != NULL){
					memcpy(curObjChg->oldObject,object , curObjChg->objSize);
			}
		}
		flagRecord = flag;
		
		if(curObjChg->flag == CMS_DB_SET_OBJECT){
			curObjChg->newObject = calloc(1, curObjChg->objSize);
			newObjPtr = cmsXmlGetObjRealAddr(xmlShmCb, curObjChg->objOffset);
			if((newObjPtr !=  NULL) && (curObjChg->newObject != NULL))
				memcpy(curObjChg->newObject, newObjPtr, curObjChg->objSize);
			else
				safe_free(curObjChg->newObject);
		}
		
	}else if(conflictFlag == 2){/*action as, set parameter, then set another parameter of this object*/
		if(curObjChg->flag == CMS_DB_SET_OBJECT){
				//curObjChg->newObject = calloc(1, curObjChg->objSize);
				newObjPtr = cmsXmlGetObjRealAddr(xmlShmCb, curObjChg->objOffset);
				if((newObjPtr != NULL) && (curObjChg->newObject != NULL))
					memcpy(curObjChg->newObject, newObjPtr, curObjChg->objSize);
				else
					safe_free(newObjPtr);
			}
	}else{/*record this object first time, malloc objchg ptr*/
		curObjChg = (cms_objChgList_t *)malloc( sizeof(cms_objChgList_t));
		if(curObjChg){
			curObjChg->objId = xmlShmCb->OID;
			curObjChg->objIA = xmlShmCb->IA;
			curObjChg->objOffset = xmlShmCb->offset;
			curObjChg->objSize = xmlShmCb->objectSize;
			curObjChg->flag = flag;
			flagRecord = flag;
			curObjChg->oldObject = NULL;
			curObjChg->newObject = NULL;

			if(curObjChg->flag != CMS_DB_ADD_OBJECT){
				if(object != NULL){
					curObjChg->oldObject = calloc(1, curObjChg->objSize);
					if(curObjChg->oldObject)
						memcpy(curObjChg->oldObject,object , curObjChg->objSize);
				}
			}

			if(curObjChg->flag == CMS_DB_SET_OBJECT){
				curObjChg->newObject = calloc(1, curObjChg->objSize);
				newObjPtr = cmsXmlGetObjRealAddr(xmlShmCb, curObjChg->objOffset);
				if((newObjPtr != NULL) && (curObjChg->newObject != NULL))
					memcpy(curObjChg->newObject, newObjPtr, curObjChg->objSize);
				else
					safe_free(newObjPtr);
			}
			
			CMS_LOG(LL_DEBUG, "record, cur  object  size is %d, objID %d, objIA %"PRIx64", objOffset %d, flag 0x%x\n",
				curObjChg->objSize, curObjChg->objId, curObjChg->objIA, curObjChg->objOffset, curObjChg->flag);
			INSERT_NODE(dbQ->objChgList, curObjChg);
			dbQ->recordObjFlag = 1;
		}else{
			CMS_LOG(LL_ERROR, "objchg list malloc fail.\n");
			return -1;
		}
	}
	
	return 0;
}

void cmsDb_dbusNotify(cms_dbQueue_t *dbQ)
{
#ifdef DBUS_OBJECT_NOTIFY
#ifdef GC_APPS_CTC
	if(dbQ->xmlShmCb->srcFromDbus == TRUE)
		dbQ->xmlShmCb->srcFromDbus = FALSE;
#endif
	cms_dbusNotify_t *curDbusObj = NULL, *tmpDbusObj = NULL;
	char objInfo[EVENT_CONTENT_MAX] = {0};
	uint32_t objID = 0;
	int32_t objIDRecord = -1;
	uint64_t objIA = 0;
	int sendFlag = 0;
	int dbusQId = -1;
	cmsBoolean isNeedNotify = FALSE;
	
	if(g_dbusObj_list != NULL){
		curDbusObj = g_dbusObj_list;
		dbusQId = cms_getModuleIdByName(CMS_DBUS);
		while(curDbusObj){
			objID = cmsXml_GetOIDByOffset(dbQ->xmlShmCb, curDbusObj->objOff);
			objIA = cmsXmlGetPreObjIA(dbQ->xmlShmCb, curDbusObj->objOff);
			CMS_LOG(LL_INFO, "cms dubs is not NULL, objID %d\n", objID);

			isNeedNotify= cmsXml_checkobjNeedNotify(dbQ->xmlShmCb, objID);
			/*notify dbus*/
	#ifdef GC_APPS_CTC
			if((objID == -1) || (dbQ->pMsg->header.srcModuleId == dbusQId) || (isNeedNotify  == FALSE)){
	#else
			if((objID == -1) || (isNeedNotify == FALSE)){
	#endif	
				CMS_LOG(LL_INFO, "objId %d, dbus process module id %d, msg module id %d, isNeedNotify %d.\n ",
					objID, dbusQId, dbQ->pMsg->header.srcModuleId, isNeedNotify);
				tmpDbusObj = curDbusObj;
				curDbusObj = curDbusObj->next;
				DELETE_NODE(g_dbusObj_list, tmpDbusObj);
				continue;
			}
			
			if(objID != objIDRecord){
				sendFlag = 0;
				objIDRecord = objID;
				if(strlen(objInfo) != 0){
					cms_eventNotify(CMS_EVENT_OBJ_NOTIFY_DBUS, PARAMETER_TYPE_STRING, objInfo);
					CMS_LOG(LL_INFO, "dbus event info %s.", objInfo);
				}
			}
			
			if(sendFlag == 0){
				memset(objInfo, 0, EVENT_CONTENT_MAX);
				sprintf(objInfo, "%u;%ju;%d", objID, objIA, CMS_OBJ_SET);
				sendFlag = 1;
			}
	
			if((strlen(objInfo) + strlen(curDbusObj->paramName)) >= EVENT_CONTENT_MAX){
				cms_eventNotify(CMS_EVENT_OBJ_NOTIFY_DBUS, PARAMETER_TYPE_STRING, objInfo);
				CMS_LOG(LL_INFO, "dbus event info %s.", objInfo);
				memset(objInfo, 0, EVENT_CONTENT_MAX);
				sprintf(objInfo, "%u;%ju;%d;%s", objID, objIA, CMS_OBJ_SET, curDbusObj->paramName);
			}else{
				sprintf(objInfo+strlen(objInfo), ";%s", curDbusObj->paramName);
			}
			
			tmpDbusObj = curDbusObj;
			curDbusObj = curDbusObj->next;
			DELETE_NODE(g_dbusObj_list, tmpDbusObj);
		
			if((curDbusObj == NULL) && (sendFlag == 1) && (strlen(objInfo) != 0)){
				cms_eventNotify(CMS_EVENT_OBJ_NOTIFY_DBUS, PARAMETER_TYPE_STRING, objInfo);
				CMS_LOG(LL_INFO, "dbus event info %s.", objInfo);
			}
		}
	}else{
		CMS_LOG(LL_INFO, "cms dbus List is NULL.\n");
	}
#endif
}

